// Copyright 2019 The TCMalloc Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "absl/types/span.h"
#include "tcmalloc/common.h"
#include "tcmalloc/internal/config.h"
#include "tcmalloc/size_class_info.h"

GOOGLE_MALLOC_SECTION_BEGIN
namespace tcmalloc {
namespace tcmalloc_internal {

// Columns in the following tables:
// - bytes: size of the size class
// - pages: number of pages per span
// - batch: preferred number of objects for transfers between caches
// - class: size class number
// - objs: number of objects per span
// - waste/fixed: fixed per-size-class overhead due to end-of-span fragmentation
//   and other factors. For instance, if we have a 96 byte size class, and use
//   a single 8KiB page, then we will hold 85 objects per span, and have 32
//   bytes left over. There is also a fixed component of 64 bytes of TCMalloc
//   metadata per span. Together, the fixed overhead would be wasted/allocated
//   = (32 + 64) / (8192 - 32) ~= 1.2%.
// - waste/sampling: overhead due to heap sampling
//   (rounding to page size, proxy object, metadata).
// - inc: increment from the previous size class. This caps the dynamic
//   overhead component based on mismatches between the number of bytes
//   requested and the number of bytes provided by the size class. Together
//   they sum to the total overhead; for instance if you asked for a 50-byte
//   allocation that rounds up to a 64-byte size class, the dynamic overhead
//   would be 28%, and if waste were 22% it would mean (on average) 25 bytes
//   of overhead for allocations of that size.

// clang-format off
#if defined(__cpp_aligned_new) && __STDCPP_DEFAULT_NEW_ALIGNMENT__ <= 8
#if TCMALLOC_PAGE_SHIFT == 13
static_assert(kMaxSize == 262144, "kMaxSize mismatch");
static constexpr SizeClassAssumptions Assumptions{
  .has_expanded_classes = true,
  .span_size = 64,
  .sampling_interval = 2097152,
  .large_size = 1024,
  .large_size_alignment = 128,
};
static constexpr SizeClassInfo List[] = {
//                                         |    waste     |
//  bytes pages batch   class  objs |fixed sampling|    inc
  {     0,    0,    0},  //  0     0  0.00%    0.00%   0.00%
  {     8,    1,   32},  //  1  1024  0.78%    0.42%   0.00%
  {    16,    1,   32},  //  2   512  0.78%    0.42% 100.00%
  {    32,    1,   32},  //  3   256  0.78%    0.42% 100.00%
  {    64,    1,   32},  //  4   128  0.78%    0.42% 100.00%
  {    80,    1,   32},  //  5   102  1.16%    0.42%  25.00%
  {    96,    1,   32},  //  6    85  1.16%    0.42%  20.00%
  {   112,    1,   32},  //  7    73  0.97%    0.42%  16.67%
  {   128,    1,   32},  //  8    64  0.78%    0.42%  14.29%
  {   160,    1,   32},  //  9    51  1.16%    0.42%  25.00%
  {   208,    1,   32},  // 10    39  1.74%    0.42%  30.00%
  {   256,    1,   32},  // 11    32  0.78%    0.42%  23.08%
  {   312,    1,   32},  // 12    26  1.74%    0.42%  21.88%
  {   384,    1,   32},  // 13    21  2.33%    0.42%  23.08%
  {   512,    1,   32},  // 14    16  0.78%    0.42%  33.33%
  {   640,    1,   32},  // 15    12  6.98%    0.43%  25.00%
  {   896,    1,   32},  // 16     9  2.33%    0.42%  40.00%
  {  1024,    1,   32},  // 17     8  0.78%    0.42%  14.29%
  {  1408,    2,   32},  // 18    11  5.84%    0.43%  37.50%
  {  2048,    2,   32},  // 19     8  0.39%    0.42%  45.45%
  {  2688,    2,   24},  // 20     6  1.95%    0.43%  31.25%
  {  3456,    3,   18},  // 21     7  1.82%    0.43%  28.57%
  {  4096,    1,   16},  // 22     2  0.78%    0.43%  18.52%
  {  4736,    3,   13},  // 23     5  3.90%    0.43%  15.62%
  {  6144,    3,   10},  // 24     4  0.26%    0.42%  29.73%
  {  8192,    1,    8},  // 25     1  0.78%    0.03%  33.33%
  { 10240,    4,    6},  // 26     3  6.43%    0.85%  25.00%
  { 16384,    2,    4},  // 27     1  0.39%    0.03%  60.00%
  { 20480,    5,    3},  // 28     2  0.16%    1.21%  25.00%
  { 28672,    7,    2},  // 29     2  0.11%    1.60%  40.00%
  { 32768,    4,    2},  // 30     1  0.19%    0.03%  14.29%
  { 40960,    5,    2},  // 31     1  0.16%    0.03%  25.00%
  { 49152,    6,    2},  // 32     1  0.13%    0.03%  20.00%
  { 65536,    8,    2},  // 33     1  0.10%    0.03%  33.33%
  { 73728,    9,    2},  // 34     1  0.09%    0.03%  12.50%
  { 81920,   10,    2},  // 35     1  0.08%    0.03%  11.11%
  {106496,   13,    2},  // 36     1  0.06%    0.03%  30.00%
  {131072,   16,    2},  // 37     1  0.05%    0.03%  23.08%
  {155648,   19,    2},  // 38     1  0.04%    0.03%  18.75%
  {204800,   25,    2},  // 39     1  0.03%    0.03%  31.58%
  {262144,   32,    2},  // 40     1  0.02%    0.03%  28.00%
};
#elif TCMALLOC_PAGE_SHIFT == 15
static_assert(kMaxSize == 262144, "kMaxSize mismatch");
static constexpr SizeClassAssumptions Assumptions{
  .has_expanded_classes = true,
  .span_size = 64,
  .sampling_interval = 2097152,
  .large_size = 1024,
  .large_size_alignment = 128,
};
static constexpr SizeClassInfo List[] = {
//                                         |    waste     |
//  bytes pages batch   class  objs |fixed sampling|    inc
  {     0,    0,    0},  //  0     0  0.00%    0.00%   0.00%
  {     8,    1,   32},  //  1  4096  0.19%    1.60%   0.00%
  {    16,    1,   32},  //  2  2048  0.19%    1.60% 100.00%
  {    32,    1,   32},  //  3  1024  0.19%    1.60% 100.00%
  {    64,    1,   32},  //  4   512  0.19%    1.60% 100.00%
  {    80,    1,   32},  //  5   409  0.34%    1.60%  25.00%
  {   104,    1,   32},  //  6   315  0.22%    1.60%  30.00%
  {   128,    1,   32},  //  7   256  0.19%    1.60%  23.08%
  {   160,    1,   32},  //  8   204  0.58%    1.60%  25.00%
  {   200,    1,   32},  //  9   163  0.71%    1.60%  25.00%
  {   256,    1,   32},  // 10   128  0.19%    1.60%  28.00%
  {   312,    1,   32},  // 11   105  0.22%    1.60%  21.88%
  {   400,    1,   32},  // 12    81  1.32%    1.60%  28.21%
  {   512,    1,   32},  // 13    64  0.19%    1.60%  28.00%
  {   640,    1,   32},  // 14    51  0.58%    1.60%  25.00%
  {   768,    1,   32},  // 15    42  1.75%    1.60%  20.00%
  {  1024,    1,   32},  // 16    32  0.19%    1.60%  33.33%
  {  1280,    1,   32},  // 17    25  2.53%    1.60%  25.00%
  {  1536,    1,   32},  // 18    21  1.75%    1.60%  20.00%
  {  2048,    1,   32},  // 19    16  0.19%    1.60%  33.33%
  {  2304,    1,   28},  // 20    14  1.75%    1.60%  12.50%
  {  2944,    1,   22},  // 21    11  1.36%    1.60%  27.78%
  {  4096,    1,   16},  // 22     8  0.19%    1.60%  39.13%
  {  4608,    1,   14},  // 23     7  1.75%    1.60%  12.50%
  {  6528,    1,   10},  // 24     5  0.58%    1.60%  41.67%
  {  8192,    1,    8},  // 25     4  0.19%    1.60%  25.49%
  {  9344,    2,    7},  // 26     7  0.29%    1.60%  14.06%
  { 13056,    2,    5},  // 27     5  0.49%    1.60%  39.73%
  { 16384,    1,    4},  // 28     2  0.19%    1.60%  25.49%
  { 19072,    3,    3},  // 29     5  3.06%    1.62%  16.41%
  { 24576,    3,    2},  // 30     4  0.07%    1.60%  28.86%
  { 32768,    1,    2},  // 31     1  0.19%    0.03%  33.33%
  { 40960,    4,    2},  // 32     3  6.30%    3.28%  25.00%
  { 54528,    5,    2},  // 33     3  0.20%    3.16%  33.12%
  { 65536,    2,    2},  // 34     1  0.10%    0.03%  20.19%
  { 81920,    5,    2},  // 35     2  0.04%    4.72%  25.00%
  { 98304,    3,    2},  // 36     1  0.07%    0.03%  20.00%
  {114688,    7,    2},  // 37     2  0.03%    6.28%  16.67%
  {131072,    4,    2},  // 38     1  0.05%    0.03%  14.29%
  {163840,    5,    2},  // 39     1  0.04%    0.03%  25.00%
  {229376,    7,    2},  // 40     1  0.03%    0.03%  40.00%
  {262144,    8,    2},  // 41     1  0.02%    0.03%  14.29%
};
#elif TCMALLOC_PAGE_SHIFT == 18
static_assert(kMaxSize == 262144, "kMaxSize mismatch");
static constexpr SizeClassAssumptions Assumptions{
  .has_expanded_classes = true,
  .span_size = 64,
  .sampling_interval = 2097152,
  .large_size = 1024,
  .large_size_alignment = 128,
};
static constexpr SizeClassInfo List[] = {
//                                         |    waste     |
//  bytes pages batch   class  objs |fixed sampling|    inc
  {     0,    0,    0},  //  0     0  0.00%    0.00%   0.00%
  {     8,    1,   32},  //  1 32768  0.02%   12.53%   0.00%
  {    16,    1,   32},  //  2 16384  0.02%   12.53% 100.00%
  {    32,    1,   32},  //  3  8192  0.02%   12.53% 100.00%
  {    64,    1,   32},  //  4  4096  0.02%   12.53% 100.00%
  {    72,    1,   32},  //  5  3640  0.05%   12.53%  12.50%
  {    96,    1,   32},  //  6  2730  0.05%   12.53%  33.33%
  {   128,    1,   32},  //  7  2048  0.02%   12.53%  33.33%
  {   160,    1,   32},  //  8  1638  0.05%   12.53%  25.00%
  {   208,    1,   32},  //  9  1260  0.05%   12.53%  30.00%
  {   256,    1,   32},  // 10  1024  0.02%   12.53%  23.08%
  {   304,    1,   32},  // 11   862  0.06%   12.53%  18.75%
  {   384,    1,   32},  // 12   682  0.12%   12.53%  26.32%
  {   512,    1,   32},  // 13   512  0.02%   12.53%  33.33%
  {   704,    1,   32},  // 14   372  0.12%   12.53%  37.50%
  {   896,    1,   32},  // 15   292  0.22%   12.53%  27.27%
  {  1024,    1,   32},  // 16   256  0.02%   12.53%  14.29%
  {  1280,    1,   32},  // 17   204  0.41%   12.53%  25.00%
  {  1664,    1,   32},  // 18   157  0.37%   12.53%  30.00%
  {  2048,    1,   32},  // 19   128  0.02%   12.53%  23.08%
  {  2560,    1,   25},  // 20   102  0.41%   12.53%  25.00%
  {  3200,    1,   20},  // 21    81  1.15%   12.53%  25.00%
  {  4096,    1,   16},  // 22    64  0.02%   12.53%  28.00%
  {  4736,    1,   13},  // 23    55  0.66%   12.53%  15.62%
  {  6528,    1,   10},  // 24    40  0.41%   12.53%  37.84%
  {  8192,    1,    8},  // 25    32  0.02%   12.53%  25.49%
  {  9984,    1,    6},  // 26    26  1.00%   12.54%  21.88%
  { 13696,    1,    4},  // 27    19  0.76%   12.54%  37.18%
  { 16384,    1,    4},  // 28    16  0.02%   12.53%  19.63%
  { 21760,    1,    3},  // 29    12  0.41%   12.54%  32.81%
  { 26112,    1,    2},  // 30    10  0.41%   12.54%  20.00%
  { 32768,    1,    2},  // 31     8  0.02%   12.53%  25.49%
  { 43648,    1,    2},  // 32     6  0.12%   12.54%  33.20%
  { 65536,    1,    2},  // 33     4  0.02%   12.53%  50.15%
  { 87296,    1,    2},  // 34     3  0.12%   12.54%  33.20%
  {104832,    2,    2},  // 35     5  0.04%   12.54%  20.09%
  {131072,    1,    2},  // 36     2  0.02%   12.53%  25.03%
  {174720,    2,    2},  // 37     3  0.04%   12.54%  33.30%
  {262144,    1,    2},  // 38     1  0.02%    0.03%  50.04%
};
#elif TCMALLOC_PAGE_SHIFT == 12
static_assert(kMaxSize == 8192, "kMaxSize mismatch");
static constexpr SizeClassAssumptions Assumptions{
  .has_expanded_classes = false,
  .span_size = 64,
  .sampling_interval = 524288,
  .large_size = 1024,
  .large_size_alignment = 128,
};
static constexpr SizeClassInfo List[] = {
//                                         |    waste     |
//  bytes pages batch   class  objs |fixed sampling|    inc
  {     0,    0,    0},  //  0     0  0.00%    0.00%   0.00%
  {     8,    1,   32},  //  1   512  1.54%    0.91%   0.00%
  {    16,    1,   32},  //  2   256  1.54%    0.91% 100.00%
  {    32,    1,   32},  //  3   128  1.54%    0.91% 100.00%
  {    64,    1,   32},  //  4    64  1.54%    0.91% 100.00%
  {    80,    1,   32},  //  5    51  1.92%    0.91%  25.00%
  {    96,    1,   32},  //  6    42  3.08%    0.91%  20.00%
  {   128,    1,   32},  //  7    32  1.54%    0.91%  33.33%
  {   144,    1,   32},  //  8    28  3.08%    0.91%  12.50%
  {   184,    1,   32},  //  9    22  2.69%    0.91%  27.78%
  {   256,    1,   32},  // 10    16  1.54%    0.91%  39.13%
  {   336,    1,   32},  // 11    12  3.08%    0.92%  31.25%
  {   512,    1,   32},  // 12     8  1.54%    0.92%  52.38%
  {   576,    2,   32},  // 13    14  2.33%    0.92%  12.50%
  {   896,    2,   32},  // 14     9  2.33%    0.92%  55.56%
  {  1024,    2,   32},  // 15     8  0.78%    0.92%  14.29%
  {  1536,    3,   32},  // 16     8  0.52%    0.92%  50.00%
  {  2048,    4,   32},  // 17     8  0.39%    0.92%  33.33%
  {  2688,    4,   24},  // 18     6  1.95%    0.92%  31.25%
  {  3584,    7,   18},  // 19     8  0.22%    0.92%  33.33%
  {  4096,    4,   16},  // 20     4  0.39%    0.92%  14.29%
  {  6144,    3,   10},  // 21     2  0.52%    1.70%  50.00%
  {  8192,    4,    8},  // 22     2  0.39%    1.70%  33.33%
};
#else
#error "Unsupported TCMALLOC_PAGE_SHIFT value!"
#endif
#else
#if TCMALLOC_PAGE_SHIFT == 13
static_assert(kMaxSize == 262144, "kMaxSize mismatch");
static constexpr SizeClassAssumptions Assumptions{
  .has_expanded_classes = true,
  .span_size = 64,
  .sampling_interval = 2097152,
  .large_size = 1024,
  .large_size_alignment = 128,
};
static constexpr SizeClassInfo List[] = {
//                                         |    waste     |
//  bytes pages batch   class  objs |fixed sampling|    inc
  {     0,    0,    0},  //  0     0  0.00%    0.00%   0.00%
  {     8,    1,   32},  //  1  1024  0.78%    0.42%   0.00%
  {    16,    1,   32},  //  2   512  0.78%    0.42% 100.00%
  {    32,    1,   32},  //  3   256  0.78%    0.42% 100.00%
  {    64,    1,   32},  //  4   128  0.78%    0.42% 100.00%
  {    80,    1,   32},  //  5   102  1.16%    0.42%  25.00%
  {    96,    1,   32},  //  6    85  1.16%    0.42%  20.00%
  {   112,    1,   32},  //  7    73  0.97%    0.42%  16.67%
  {   128,    1,   32},  //  8    64  0.78%    0.42%  14.29%
  {   160,    1,   32},  //  9    51  1.16%    0.42%  25.00%
  {   208,    1,   32},  // 10    39  1.74%    0.42%  30.00%
  {   256,    1,   32},  // 11    32  0.78%    0.42%  23.08%
  {   320,    1,   32},  // 12    25  3.10%    0.42%  25.00%
  {   384,    1,   32},  // 13    21  2.33%    0.42%  20.00%
  {   512,    1,   32},  // 14    16  0.78%    0.42%  33.33%
  {   640,    1,   32},  // 15    12  6.98%    0.43%  25.00%
  {   896,    1,   32},  // 16     9  2.33%    0.42%  40.00%
  {  1024,    1,   32},  // 17     8  0.78%    0.42%  14.29%
  {  1408,    2,   32},  // 18    11  5.84%    0.43%  37.50%
  {  2048,    2,   32},  // 19     8  0.39%    0.42%  45.45%
  {  2688,    2,   24},  // 20     6  1.95%    0.43%  31.25%
  {  3456,    3,   18},  // 21     7  1.82%    0.43%  28.57%
  {  4096,    1,   16},  // 22     2  0.78%    0.43%  18.52%
  {  4736,    3,   13},  // 23     5  3.90%    0.43%  15.62%
  {  6144,    3,   10},  // 24     4  0.26%    0.42%  29.73%
  {  8192,    1,    8},  // 25     1  0.78%    0.03%  33.33%
  { 10240,    4,    6},  // 26     3  6.43%    0.85%  25.00%
  { 16384,    2,    4},  // 27     1  0.39%    0.03%  60.00%
  { 20480,    5,    3},  // 28     2  0.16%    1.21%  25.00%
  { 28672,    7,    2},  // 29     2  0.11%    1.60%  40.00%
  { 32768,    4,    2},  // 30     1  0.19%    0.03%  14.29%
  { 40960,    5,    2},  // 31     1  0.16%    0.03%  25.00%
  { 49152,    6,    2},  // 32     1  0.13%    0.03%  20.00%
  { 65536,    8,    2},  // 33     1  0.10%    0.03%  33.33%
  { 73728,    9,    2},  // 34     1  0.09%    0.03%  12.50%
  { 81920,   10,    2},  // 35     1  0.08%    0.03%  11.11%
  {106496,   13,    2},  // 36     1  0.06%    0.03%  30.00%
  {131072,   16,    2},  // 37     1  0.05%    0.03%  23.08%
  {155648,   19,    2},  // 38     1  0.04%    0.03%  18.75%
  {204800,   25,    2},  // 39     1  0.03%    0.03%  31.58%
  {262144,   32,    2},  // 40     1  0.02%    0.03%  28.00%
};
#elif TCMALLOC_PAGE_SHIFT == 15
static_assert(kMaxSize == 262144, "kMaxSize mismatch");
static constexpr SizeClassAssumptions Assumptions{
  .has_expanded_classes = true,
  .span_size = 64,
  .sampling_interval = 2097152,
  .large_size = 1024,
  .large_size_alignment = 128,
};
static constexpr SizeClassInfo List[] = {
//                                         |    waste     |
//  bytes pages batch   class  objs |fixed sampling|    inc
  {     0,    0,    0},  //  0     0  0.00%    0.00%   0.00%
  {     8,    1,   32},  //  1  4096  0.19%    1.60%   0.00%
  {    16,    1,   32},  //  2  2048  0.19%    1.60% 100.00%
  {    32,    1,   32},  //  3  1024  0.19%    1.60% 100.00%
  {    64,    1,   32},  //  4   512  0.19%    1.60% 100.00%
  {    80,    1,   32},  //  5   409  0.34%    1.60%  25.00%
  {   112,    1,   32},  //  6   292  0.39%    1.60%  40.00%
  {   128,    1,   32},  //  7   256  0.19%    1.60%  14.29%
  {   160,    1,   32},  //  8   204  0.58%    1.60%  25.00%
  {   192,    1,   32},  //  9   170  0.58%    1.60%  20.00%
  {   256,    1,   32},  // 10   128  0.19%    1.60%  33.33%
  {   320,    1,   32},  // 11   102  0.58%    1.60%  25.00%
  {   400,    1,   32},  // 12    81  1.32%    1.60%  25.00%
  {   512,    1,   32},  // 13    64  0.19%    1.60%  28.00%
  {   640,    1,   32},  // 14    51  0.58%    1.60%  25.00%
  {   768,    1,   32},  // 15    42  1.75%    1.60%  20.00%
  {  1024,    1,   32},  // 16    32  0.19%    1.60%  33.33%
  {  1280,    1,   32},  // 17    25  2.53%    1.60%  25.00%
  {  1536,    1,   32},  // 18    21  1.75%    1.60%  20.00%
  {  2048,    1,   32},  // 19    16  0.19%    1.60%  33.33%
  {  2304,    1,   28},  // 20    14  1.75%    1.60%  12.50%
  {  2944,    1,   22},  // 21    11  1.36%    1.60%  27.78%
  {  4096,    1,   16},  // 22     8  0.19%    1.60%  39.13%
  {  4608,    1,   14},  // 23     7  1.75%    1.60%  12.50%
  {  6528,    1,   10},  // 24     5  0.58%    1.60%  41.67%
  {  8192,    1,    8},  // 25     4  0.19%    1.60%  25.49%
  {  9344,    2,    7},  // 26     7  0.29%    1.60%  14.06%
  { 13056,    2,    5},  // 27     5  0.49%    1.60%  39.73%
  { 16384,    1,    4},  // 28     2  0.19%    1.60%  25.49%
  { 19072,    3,    3},  // 29     5  3.06%    1.62%  16.41%
  { 24576,    3,    2},  // 30     4  0.07%    1.60%  28.86%
  { 32768,    1,    2},  // 31     1  0.19%    0.03%  33.33%
  { 40960,    4,    2},  // 32     3  6.30%    3.28%  25.00%
  { 54528,    5,    2},  // 33     3  0.20%    3.16%  33.12%
  { 65536,    2,    2},  // 34     1  0.10%    0.03%  20.19%
  { 81920,    5,    2},  // 35     2  0.04%    4.72%  25.00%
  { 98304,    3,    2},  // 36     1  0.07%    0.03%  20.00%
  {114688,    7,    2},  // 37     2  0.03%    6.28%  16.67%
  {131072,    4,    2},  // 38     1  0.05%    0.03%  14.29%
  {163840,    5,    2},  // 39     1  0.04%    0.03%  25.00%
  {229376,    7,    2},  // 40     1  0.03%    0.03%  40.00%
  {262144,    8,    2},  // 41     1  0.02%    0.03%  14.29%
};
#elif TCMALLOC_PAGE_SHIFT == 18
static_assert(kMaxSize == 262144, "kMaxSize mismatch");
static constexpr SizeClassAssumptions Assumptions{
  .has_expanded_classes = true,
  .span_size = 64,
  .sampling_interval = 2097152,
  .large_size = 1024,
  .large_size_alignment = 128,
};
static constexpr SizeClassInfo List[] = {
//                                         |    waste     |
//  bytes pages batch   class  objs |fixed sampling|    inc
  {     0,    0,    0},  //  0     0  0.00%    0.00%   0.00%
  {     8,    1,   32},  //  1 32768  0.02%   12.53%   0.00%
  {    16,    1,   32},  //  2 16384  0.02%   12.53% 100.00%
  {    32,    1,   32},  //  3  8192  0.02%   12.53% 100.00%
  {    64,    1,   32},  //  4  4096  0.02%   12.53% 100.00%
  {    80,    1,   32},  //  5  3276  0.05%   12.53%  25.00%
  {    96,    1,   32},  //  6  2730  0.05%   12.53%  20.00%
  {   128,    1,   32},  //  7  2048  0.02%   12.53%  33.33%
  {   160,    1,   32},  //  8  1638  0.05%   12.53%  25.00%
  {   208,    1,   32},  //  9  1260  0.05%   12.53%  30.00%
  {   256,    1,   32},  // 10  1024  0.02%   12.53%  23.08%
  {   304,    1,   32},  // 11   862  0.06%   12.53%  18.75%
  {   384,    1,   32},  // 12   682  0.12%   12.53%  26.32%
  {   512,    1,   32},  // 13   512  0.02%   12.53%  33.33%
  {   704,    1,   32},  // 14   372  0.12%   12.53%  37.50%
  {   896,    1,   32},  // 15   292  0.22%   12.53%  27.27%
  {  1024,    1,   32},  // 16   256  0.02%   12.53%  14.29%
  {  1280,    1,   32},  // 17   204  0.41%   12.53%  25.00%
  {  1664,    1,   32},  // 18   157  0.37%   12.53%  30.00%
  {  2048,    1,   32},  // 19   128  0.02%   12.53%  23.08%
  {  2560,    1,   25},  // 20   102  0.41%   12.53%  25.00%
  {  3200,    1,   20},  // 21    81  1.15%   12.53%  25.00%
  {  4096,    1,   16},  // 22    64  0.02%   12.53%  28.00%
  {  4736,    1,   13},  // 23    55  0.66%   12.53%  15.62%
  {  6528,    1,   10},  // 24    40  0.41%   12.53%  37.84%
  {  8192,    1,    8},  // 25    32  0.02%   12.53%  25.49%
  {  9984,    1,    6},  // 26    26  1.00%   12.54%  21.88%
  { 13696,    1,    4},  // 27    19  0.76%   12.54%  37.18%
  { 16384,    1,    4},  // 28    16  0.02%   12.53%  19.63%
  { 21760,    1,    3},  // 29    12  0.41%   12.54%  32.81%
  { 26112,    1,    2},  // 30    10  0.41%   12.54%  20.00%
  { 32768,    1,    2},  // 31     8  0.02%   12.53%  25.49%
  { 43648,    1,    2},  // 32     6  0.12%   12.54%  33.20%
  { 65536,    1,    2},  // 33     4  0.02%   12.53%  50.15%
  { 87296,    1,    2},  // 34     3  0.12%   12.54%  33.20%
  {104832,    2,    2},  // 35     5  0.04%   12.54%  20.09%
  {131072,    1,    2},  // 36     2  0.02%   12.53%  25.03%
  {174720,    2,    2},  // 37     3  0.04%   12.54%  33.30%
  {262144,    1,    2},  // 38     1  0.02%    0.03%  50.04%
};
#elif TCMALLOC_PAGE_SHIFT == 12
static_assert(kMaxSize == 8192, "kMaxSize mismatch");
static constexpr SizeClassAssumptions Assumptions{
  .has_expanded_classes = false,
  .span_size = 64,
  .sampling_interval = 524288,
  .large_size = 1024,
  .large_size_alignment = 128,
};
static constexpr SizeClassInfo List[] = {
//                                         |    waste     |
//  bytes pages batch   class  objs |fixed sampling|    inc
  {     0,    0,    0},  //  0     0  0.00%    0.00%   0.00%
  {     8,    1,   32},  //  1   512  1.54%    0.91%   0.00%
  {    16,    1,   32},  //  2   256  1.54%    0.91% 100.00%
  {    32,    1,   32},  //  3   128  1.54%    0.91% 100.00%
  {    64,    1,   32},  //  4    64  1.54%    0.91% 100.00%
  {    80,    1,   32},  //  5    51  1.92%    0.91%  25.00%
  {    96,    1,   32},  //  6    42  3.08%    0.91%  20.00%
  {   128,    1,   32},  //  7    32  1.54%    0.91%  33.33%
  {   144,    1,   32},  //  8    28  3.08%    0.91%  12.50%
  {   192,    1,   32},  //  9    21  3.08%    0.92%  33.33%
  {   256,    1,   32},  // 10    16  1.54%    0.91%  33.33%
  {   336,    1,   32},  // 11    12  3.08%    0.92%  31.25%
  {   512,    1,   32},  // 12     8  1.54%    0.92%  52.38%
  {   576,    2,   32},  // 13    14  2.33%    0.92%  12.50%
  {   896,    2,   32},  // 14     9  2.33%    0.92%  55.56%
  {  1024,    2,   32},  // 15     8  0.78%    0.92%  14.29%
  {  1536,    3,   32},  // 16     8  0.52%    0.92%  50.00%
  {  2048,    4,   32},  // 17     8  0.39%    0.92%  33.33%
  {  2688,    4,   24},  // 18     6  1.95%    0.92%  31.25%
  {  3584,    7,   18},  // 19     8  0.22%    0.92%  33.33%
  {  4096,    4,   16},  // 20     4  0.39%    0.92%  14.29%
  {  6144,    3,   10},  // 21     2  0.52%    1.70%  50.00%
  {  8192,    4,    8},  // 22     2  0.39%    1.70%  33.33%
};
#else
#error "Unsupported TCMALLOC_PAGE_SHIFT value!"
#endif
#endif
// clang-format on

static_assert(sizeof(List) / sizeof(List[0]) <= kNumBaseClasses);
extern constexpr SizeClasses kReuseSizeClassesV2{List, Assumptions};

}  // namespace tcmalloc_internal
}  // namespace tcmalloc
GOOGLE_MALLOC_SECTION_END
